﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Configuration;

namespace PKSpeed
{
    class Program
    {
        /// <summary>
        /// 单例命令对象
        /// </summary>
        public static readonly PKCommand CurrentCommand =new PKCommand();
        /// <summary>
        /// 当前用户信息，即用户名和路径
        /// </summary>
        private static String CurrentInfo
        {
            get
            {
                //没有当前用户时，要求登录
                if (CurrentCommand.CurrentUser == null)
                {
                    return "@SeedCup " + CurrentCommand.CurrentPath + " $ ";
                }
                return CurrentCommand.CurrentUser + "@SeedCup " + CurrentCommand.CurrentPath + " $ ";
            }
        }

         static void Main(string[] args)
        {
            //初始化HashCommand，以备用
            HashCommand.InitializeHashTable();
            while(true)
            {
                //登录
                while (String.IsNullOrEmpty(CurrentCommand.CurrentUser))
                {
                    UserOperation.Login();
                    if(ErrorLog.ErrorTest())
                    {
                        Console.WriteLine("上次退出出错，是否修复错误？输入Y(y)确认，其他输入取消");
                        ConsoleKeyInfo flag = Console.ReadKey();
                        if(flag.KeyChar=='y'||flag.KeyChar=='Y')
                        {
                            Console.Write("\n" + CurrentInfo);
                            ErrorLog.Fix();
                        }
                        else
                        {
                            ErrorLog.OperationEnd();
                        }

                    }
                }
                //输出提示符信息
                Console.Write("\n" + CurrentInfo);
                String cmdStr = HandleKey();
                
                //历史输入
                CurrentCommand.HistoryInput[CurrentCommand.HistoryInputPointer++] = cmdStr;
                CurrentCommand.HistoryInputPointer %= 11;
                //如果没有输入或者输入全为空格
                if (String.IsNullOrEmpty(cmdStr) || Regex.IsMatch(cmdStr, "^[\\s]{1,}$"))
                {
                    continue;
                }
                String[] singleCmds = cmdStr.Split(';');
                for (int i = 0; i < singleCmds.Length; i++)
                {
                    if (String.IsNullOrEmpty(singleCmds[i]) || Regex.IsMatch(singleCmds[i], "^[\\s]{1,}$"))
                    {
                        continue;
                    }
                    String singleCmd = ExtraOperation.AliasRecovery(singleCmds[i]);
                    if ((!CurrentCommand.Start(singleCmd) || !CurrentCommand.Get() || !CurrentCommand.Execute()) &&
                        singleCmds.Length > 1)
                    {
                        Console.WriteLine("第{0}条命令（{1}）发生错误！", i + 1, singleCmds[i]);
                        break;
                    }
                }
            }
        }

        //读取字符串同时按照控制键进行操作
        private static String HandleKey()
        {
            int tabCount = 0;
            ConsoleKeyInfo keyInfo;
            int hp = CurrentCommand.HistoryInputPointer;//历史记录游标
            String cmdStr = "";
            do
            {
                keyInfo = Console.ReadKey(true);
                // Tab键
                if (keyInfo.Key == ConsoleKey.Tab)
                {
                    String newCmdStr = ExtraOperation.Tab(cmdStr, false,ref tabCount);
                    if(cmdStr == newCmdStr)
                    {
                        tabCount++;
                    }
                    cmdStr = newCmdStr;
                    if (Console.CursorLeft == 0 && tabCount != 2)//如果光标在最左边
                    {
                        tabCount = 0;
                        Console.Write("\n" + CurrentInfo + cmdStr);
                    }
                    else if(tabCount != 2)//如果是匹配当前输入
                    {
                        Console.CursorLeft = CurrentInfo.Length;
                        Console.Write(cmdStr);
                    }
                    else//如果是匹配最长串完毕后第二次按TAB键
                    {
                        ExtraOperation.Tab(cmdStr, true, ref tabCount);
                        tabCount = 0;
                        Console.CursorLeft = 0;
                        Console.Write("\n" + CurrentInfo + cmdStr);
                    }
                    continue;
                }
                //上箭头
                if (keyInfo.Key == ConsoleKey.UpArrow && !String.IsNullOrEmpty(CurrentCommand.HistoryInput[(hp + 10) % 11]) && (hp + 10)%11 != CurrentCommand.HistoryInputPointer)
                {
                    tabCount = 0;
                    int oldLength = cmdStr.Length;
                    hp = (hp + 10)%11;
                    cmdStr = CurrentCommand.HistoryInput[hp];
                    String extra = "";
                    if (oldLength - cmdStr.Length > 0)
                    {
                        extra = new string(' ', oldLength - cmdStr.Length);
                    }
                    Console.CursorLeft = CurrentInfo.Length;
                    Console.Write(cmdStr + extra);
                    Console.CursorLeft = CurrentInfo.Length + cmdStr.Length;
                    continue;
                }
                //下箭头
                if (keyInfo.Key == ConsoleKey.DownArrow && !String.IsNullOrEmpty(CurrentCommand.HistoryInput[(hp + 1) % 11]) && (hp + 1) % 11 != CurrentCommand.HistoryInputPointer)
                {
                    tabCount = 0;
                    int oldLength = cmdStr.Length;
                    hp = (hp + 1) % 11;
                    cmdStr = CurrentCommand.HistoryInput[hp];
                    String extra = "";
                    if (oldLength - cmdStr.Length > 0)
                    {
                        extra = new string(' ', oldLength - cmdStr.Length);
                    }
                    Console.CursorLeft = CurrentInfo.Length;
                    Console.Write(cmdStr + extra);
                    Console.CursorLeft = CurrentInfo.Length + cmdStr.Length;
                    continue;
                }
                // 操作退格键
                if (keyInfo.Key == ConsoleKey.Backspace)
                {
                    tabCount = 0;
                    // 字符串是否为空
                    if (cmdStr.Length >= 1)
                    {
                        // 控制台缓冲区
                        int cursorCol = Console.CursorLeft - 1;
                        int oldLength = cmdStr.Length;
                        int extraRows = oldLength / 80;

                        cmdStr = cmdStr.Substring(0, oldLength - 1);
                        Console.CursorLeft = CurrentInfo.Length;
                        Console.CursorTop = Console.CursorTop - extraRows;
                        Console.Write(cmdStr + new String(' ', oldLength - cmdStr.Length));
                        Console.CursorLeft = cursorCol;
                    }
                    continue;
                }
                //需要忽略的键
                if ((keyInfo.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt
                    || (keyInfo.Modifiers & ConsoleModifiers.Control) == ConsoleModifiers.Control// 忽略Alt or Ctrl
                    || keyInfo.KeyChar == '\u0000'// 忽略F1 F2....
                    || keyInfo.Key == ConsoleKey.Escape)// Esc键
                {
                    continue;
                }
                if (keyInfo.Key == ConsoleKey.Enter)
                {
                    Console.Write("\n");
                }
                else
                {
                    tabCount = 0;
                    Console.Write(keyInfo.KeyChar);
                    cmdStr += keyInfo.KeyChar;
                }
            } while (keyInfo.Key != ConsoleKey.Enter);

            return cmdStr;
        }
    }
}
